using System;
using System.Collections;
using System.Configuration;
using System.Net.Mail;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.Web.Services3.Design;
using PHSRAG.Insight21.CDS;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.FormsManagement;
using PHSRAG.Insight21.InsightWorkFlow;
using PHSRAG.Insight21.Policy;
using PHSRAG.Insight21.ScriptEngine;
using PHSRAG.Utility;
using Workflow.NET.ActionHandler;
using Forms = PHSRAG.Insight21.FormsManagement;
using ScriptReference=PHSRAG.Insight21.ScriptEngine.ScriptReference;
using SkeltaWFlow = PHSRAG.Insight21.InsightWorkFlow;
using SkeltaActionHandler = Workflow.NET.ActionHandler;
using System.IO;
using InsightServiceUtility;

namespace PHSRAG.Insight21.Humans
{
    /// <summary>
    /// The ProtocolProcessSubmission facilitates the user to submit the questionnaire(answered)to the review board:
    /// The Submission is carried out in four stages and are as follows
    /// 1.Initial review :validates the answers given for the questionnaire by the logged in user(Required/Script validation). 
    /// 2.The error if any obtained in Step: 1 will be displayed(in a grid)to the user for correction.
    ///  The errors should be corrected by clicking the logItem ,which opens the Questionnaire viewer for editing as a popup.
    /// 3.When its done with error correction ,the Submit page is displayed allowing the user to view the application(questionnaire) 
    ///  that will be submitted to the review board.
    /// 4.The user will be acknowledged once the questionnaire is submitted to the review board in Step: 3 via Skelta work flow.
    /// </summary>
    public partial class ProtocolProcessSubmission : BasePage
    {
        #region instance variables (Private)

        /// <summary> Policy used for caching objects to be used across pages.</summary>
        private ICachePolicy cachePolicy;

        private Hashtable pageCache;

        /// <summary> Policy used for caching Contexts to be used across pages </summary>
        private ICachePolicy pageCachePolicy;

        private Protocol protocol;
        private int protocolId;
        private ProtocolProcess protocolProcess;
        private int protocolProcessId;
        private int resubmissionFlag = -1;

        /// <summary>Workflow helper object</summary>
        private HumansWorkFlow skeltaWF;

        private int userAccessLevel;

        /// <summary>Workflow execution Id</summary>
        private int workflowExecutionID = -1;

        #endregion

        #region Constants

        private const string AnnunciatorTitle = "The following error(s) occurred...";
        private const string CachedProtocolIdKey = "CachedProtocolIdKey_1168826E-4ECF-472e-98F4-50DC6E4CC842";
        private const string CRSubmittedErrorMsg = "&nbsp&nbspA continuing review has already been submitted for this protocol.  The submission can be viewed from the Pending Applications page.";

        /// <summary>page CacheKey to hold the page related objects</summary>
        private const string PageCacheKey = "protocolProcessSubmission_1168826E-4ECF-472e-98F4-50DC6E4CC842";

        private const string UncacheObjects = "UnCacheObjects";

        /// <summary>Workflow name</summary>
        private const string WorkflowName = "EIRBWF";

        #endregion

        #region private properties

        /// <summary>
        /// Gets the protocol .If it's not already in the cache, it loads it up based on the protocolId passed to the page, and caches the object
        /// </summary>
        private Protocol Protocol
        {
            get
            {
                protocol = cachePolicy.GetCachedObject(Protocol.ProtocolKey) as Protocol;

                if ((protocol == null) || (protocolId != protocol.Id))
                {
                    protocol = new Protocol(cachePolicy);
                    protocol.Load(DataAccess.GetConnectionString(), protocolId);
                    cachePolicy.Cache(Protocol.ProtocolKey, protocol);
                }
                return protocol;
            }
        }

        /// <summary>
        /// Gets the protocol process . If it's not already
        /// in the cache, it loads it up based on the protocolProcessId passed to the page, and caches the 
        /// object
        /// </summary>
        private ProtocolProcess ProtocolProcess
        {
            get
            {
                protocolProcess =
                    cachePolicy.GetCachedObject(ProtocolProcess.ProtocolProcessKey) as ProtocolProcess;

                if ((protocolProcess == null) || (protocolProcessId != protocolProcess.Id))
                {
                    if (0 == protocolProcessId)
                    {
                        protocolProcess = null;
                    }
                    else
                    {
                        protocolProcess = ProtocolProcess.GetProtocolProcess(
                            DataAccess.GetConnectionString(), protocolProcessId, cachePolicy, null);
                        cachePolicy.Cache(ProtocolProcess.ProtocolProcessKey, protocolProcess);
                    }
                }

                if (null == protocolProcess)
                {
                    throw new Exception("No protocol process available.");
                }

                return protocolProcess;
            }
        }

        /// <summary>
        /// Gets the HumansWorkFlow object for use in this page
        /// </summary>
        private HumansWorkFlow SkeltaWF
        {
            get
            {
                if (skeltaWF == null)
                {
                    skeltaWF = new HumansWorkFlow(cachePolicy);
                }
                return skeltaWF;
            }
        }

        /// <summary>
        /// Indicates whether the workflow was declined and sent back to submitter.
        /// </summary>
        private bool ResubmissionFlag
        {
            get
            {
                if (resubmissionFlag == -1)
                {
                    resubmissionFlag = 0;
                    if (WorkflowExecutionID != 0)
                    {
                        string type = protocolProcess.Resubmission ? Constants.WorkFlow.Resubmission : Constants.WorkFlow.Initial;
                        //GetReubmissionFlag will throw an exception when it doesn't get resubmissionflag variable.
                        //Which can occur only when WorkflowItem is not present in Workflow Server.
                        //This can happen if there is some runtime problem which we can not handle in Workflow design.
                        //More explanation for this - 
                        //All custom actions runtime failures are handled in Workflow design. Admin gets notified and gets choice to clean the item properly.
                        //But some place where it gives problem from Skelta in-built steps Workflow gets ended automatically. This should happen rarely in stable system.
                        //To take care of this prblem the following try catch is needed so that the error will be taken care gracefully.
                        try
                        {
                            resubmissionFlag = SkeltaWF.GetResubmissionFlag(ProtocolProcess.Id, type);
                        }
                        catch (Exception ex)
                        {
                            //Make sure that we are trapping this error in the log and give comparitively more user friendly message.
                            ExceptionReport.WriteToEventLog("Error occurred while getting resubmission flag", ex, true, ExceptionReport.ReportType.Error);
                            throw new Exception("No Workflow item available for this protocol");
                        }
                    }
                }
                return (resubmissionFlag == 1);
            }
        }

        private int WorkflowExecutionID
        {
            get
            {
                if (workflowExecutionID == -1)
                {
                    string type = protocolProcess.Resubmission ? Constants.WorkFlow.Resubmission : Constants.WorkFlow.Initial;
                    workflowExecutionID = GetWorkflowExecutionId(type);
                }
                return workflowExecutionID;
            }
        }

        #endregion

        #region Page event handlers

        /// <summary>
        /// Page load event handler
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnPageLoad(object sender, EventArgs e)
        {
            breadCrumb.Add(
                "Submission",
                Settings.GetKeyValue("SubModuleNavigation.Humans.SubmissionURL", ""),
                Settings.GetKeyValue("BreadCrumb.DetailPageLevel", 2));

            annunciator.Message = string.Empty;
            string moduleName = header.ModuleName.ToLower();
            initialInstructions.Text = (moduleName == "humans") ? Settings.GetKeyValue("Humans.initialInstruction", "") : Settings.GetKeyValue("Animals.InitialInstruction", "");
            reviewInstructions.Text = (moduleName == "humans") ? Settings.GetKeyValue("Humans.reviewInstructions", "") : Settings.GetKeyValue("Animals.reviewInstructions", "");
            submitInstructions.Text = (moduleName == "humans") ? Settings.GetKeyValue("Humans.submitInstructions", "") : Settings.GetKeyValue("Animals.submitInstructions", "");
            resubmitInstructions.Text = (moduleName == "humans") ? Settings.GetKeyValue("Humans.resubmitInstructions", "") : Settings.GetKeyValue("Animals.resubmitInstructions", "");
            resubmitErrorInstructions.Text = (moduleName == "humans") ? Settings.GetKeyValue("Humans.resubmitErrorInstructions", "") : Settings.GetKeyValue("Animals.resubmitErrorInstructions", "");
            submitComplete.Text = (moduleName == "humans") ? Settings.GetKeyValue("Humans.submitComplete", "") : Settings.GetKeyValue("Animals.submitComplete", "");
            resubmitInitialInstructions.Text = (moduleName == "humans") ? Settings.GetKeyValue("Humans.resubmitInitialInstructions", "") : Settings.GetKeyValue("Animals.resubmitInitialInstructions", "");
            resubmitComplete.Text = (moduleName == "humans") ? Settings.GetKeyValue("Humans.resubmitComplete", "") : Settings.GetKeyValue("Animals.resubmitComplete", "");

            try
            {
                pageCache = pageCachePolicy.GetCachedObject(PageCacheKey) as Hashtable ?? new Hashtable();

                if (!IsPostBack)
                {
                    // get id coming from the originating page and clean the cache of all incoming data
                    Hashtable incomingPageHash = cachePolicy.GetCachedObject(Keys.IncomingDataKey) as Hashtable;
                    if (incomingPageHash != null)
                    {
                        // Pull incoming data out of cache and store under the page's cache
                        protocolId = Convert.ToInt32(incomingPageHash[Keys.ProtocolIdKey]);
                        protocolDetailHeader.ProtocolID = protocolId;
                        protocolProcessId = Convert.ToInt32(incomingPageHash[Keys.ProtocolProcessIdKey]);
                        userAccessLevel = Convert.ToInt32(incomingPageHash[Keys.ProtocolAccessKey]);
                        cachePolicy.UnCache(Keys.IncomingDataKey);

                        // get any data that's been cached from previous hits to the page;
                        // if there's data in the cache for this page, and if the protocolId is different 
                        // than the one for which data is cached, flush the cache
                        object cachedProtId = pageCache[CachedProtocolIdKey];
                        if (cachedProtId != null)
                        {
                            int cachedId = Convert.ToInt32(cachedProtId);
                            if (cachedId != protocolId)
                            {
                                UnCachePageData();
                            }
                        }
                        else
                        {
                            UnCachePageData();
                        }

                        pageCache[CachedProtocolIdKey] = protocolId;
                        pageCache[Keys.ProtocolProcessIdKey] = protocolProcessId;
                        pageCache[Keys.ProtocolAccessKey] = userAccessLevel;
                        pageCachePolicy.Cache(PageCacheKey, pageCache);
                    }
                    else
                    {
                        protocolId = (int) pageCache[CachedProtocolIdKey];
                        protocolDetailHeader.ProtocolID = protocolId;
                    }

                    if (ProtocolProcess.Validated)
                    {
                        if (ResubmissionFlag)
                        {
                            SetSubmissionStage(SubmissionStage.Submit);
                        }
                        else
                        {
                            if (!ProtocolProcess.Locked && ProtocolProcess.BeenSubmitted && !ProtocolProcess.HasBeenLocked)
                            {
                                SetSubmissionStage(SubmissionStage.ResubmissionNoWF);
                            }
                            else if (!ProtocolProcess.Locked && ProtocolProcess.BeenSubmitted && ProtocolProcess.HasBeenLocked && protocolProcess.Resubmission)
                            {
                                SetSubmissionStage(SubmissionStage.Resubmission);
                            }
                            else
                            {
                                SetSubmissionStage(SubmissionStage.Submit);
                            }
                        }
                    }
                    else
                    {
                        ArrayList logItems = LogItem.GetLogItems(protocolProcessId, cachePolicy);
                        if (0 == logItems.Count)
                        {
                            SetSubmissionStage(SubmissionStage.InitialReview);
                        }
                        else
                        {
                            SetSubmissionStage(SubmissionStage.ErrorReview, logItems);
                        }
                    }
                }
                else
                {
                    protocolId = (int) pageCache[CachedProtocolIdKey];
                    protocolDetailHeader.ProtocolID = protocolId;
                    protocolProcessId = (int) pageCache[Keys.ProtocolProcessIdKey];
                    userAccessLevel = (int) pageCache[Keys.ProtocolAccessKey];
                }

                if (submitApplication.ImageUrl != "../Images/b_resubmit.gif") //See whether resubmit is enabled or not. 
                    //Better way of doing it is to check the resubmision flag but it expensive
                {
                    reSubmission.Visible = false;
                    instructions.Visible = true;
                }

                SetupPageForModuleType();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);

                HideControls();
            }
        }

        /// <summary>
        /// Make necessary changes to page for use by Animals or Humans
        /// </summary>
        protected void SetupPageForModuleType()
        {
            if (Protocol.ModuleType == Constants.ModuleType.Animals)
            {
                animalsSubModNavigation.Visible = true;
                humansSubModNavigation.Visible = false;
                animalsSubModNavigation.ProtocolProcess = ProtocolProcess;
                animalsSubModNavigation.Protocol = Protocol;
                animalsSubModNavigation.SelectedLink = "Submission";

                //Set Human subModNavigation Links
                //animalsSubModNavigation.Protocol = Protocol;
                //animalsSubModNavigation.ProtocolProcess = ProtocolProcess;
            }
            else
            {
                //Set the Human sub mod Navigation links
                humansSubModNavigation.Visible = true;
                animalsSubModNavigation.Visible = false;
                humansSubModNavigation.ProtocolProcess = ProtocolProcess;
                humansSubModNavigation.Protocol = Protocol;
                humansSubModNavigation.SelectedLink = "Submission";

                //Set Human subModNavigation Links
                //humansSubModNavigation.Protocol = Protocol;
                //humansSubModNavigation.ProtocolProcess = ProtocolProcess;
            }
        }

        /// <summary>
        /// Displays an error message on the screen to the user with the exception, and all
        /// inner exception messages.
        /// </summary>
        /// <param name="ex">The exception to report on</param>
        private void DisplayExceptionReport(Exception ex)
        {
            annunciator.Title = AnnunciatorTitle;
            annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
        }

        /// <summary>
        /// Resets the hash table that stores page data, and also the cachedProtocolId, 
        /// </summary>
        private void UnCachePageData()
        {
            pageCachePolicy.UnCache(CachedProtocolIdKey);

            pageCache = new Hashtable();
            pageCachePolicy.Cache(PageCacheKey, pageCache);
        }

        /// <summary>
        /// Event handler for Application review button click
        /// </summary>
        /// <param name="source">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnApplicationReview(object source, ImageClickEventArgs e)
        {
            // disasble the links here for the errorGrid
            foreach (DataGridItem item in errorGrid.Items)
            {
                LinkButton linkControl =
                    (LinkButton) item.Cells[3].Controls[0];

                //get rid of the link and add a literal
                item.Cells[3].Controls.Clear();
                item.Cells[3].Controls.Add(new LiteralControl(linkControl.Text));
            }

            try
            {
                Validate(UserRequest.ApplicationReview);
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Event handler for Application Submit button click
        /// </summary>
        /// <param name="source">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnApplicationSubmit(object source, ImageClickEventArgs e)
        {
            try
            {
                // added for track it 9616
                if (protocolProcess.Type == Constants.ProtocolProcessType.ContinuingReview)
                {
                    ValidateSubmissionStatus(protocolProcess, Protocol);
                }

                int workflowExecutionID = SkeltaWF.GetLatestSubmitterActivityId(WorkflowExecutionID);

                // In the case where we need to send an email, reget the execution ID
                if (workflowExecutionID == 0)
                {
                    workflowExecutionID = WorkflowExecutionID;
                }

                if ((!protocolProcess.BeenSubmitted) && !protocolProcess.Locked && !protocolProcess.HasBeenLocked)
                {
                    Validate(UserRequest.ApplicationSubmit);
                    if (protocolProcess.Validated)
                    {
                        protocolProcess.BeenSubmitted = true;
                        protocolProcess.Status = "PPSTATUS_PEND";
                        protocolProcess.Save(DataAccess.GetConnectionString());
                    }
                }
                else if (!protocolProcess.BeenSubmitted && !protocolProcess.Locked && !protocolProcess.HasBeenLocked)
                {
                    Validate(UserRequest.ResubmitWF);
                }
                    //If the the process been submitted, not locked, not been locked and has not come as regular rejection process from the user to submitter
                else if (protocolProcess.BeenSubmitted && !protocolProcess.Locked && !protocolProcess.HasBeenLocked && !ResubmissionFlag && workflowExecutionID != 0)
                {
                    Validate(UserRequest.Resubmit);
                    if (protocolProcess.Validated)
                    {
                        //Before sending an e-mail to PI make sure that PI is signed-of. 
                        //If PI has not signed off then do not send an e-mail                        
                        if (HumansWorkFlow.HasPISignedOff(workflowExecutionID))
                        {
                            // Send an email to the PI denoting that the application has been changed.
                            Person PIPerson = new Person(cachePolicy);
                            PIPerson.Load(DataAccess.GetConnectionString(), protocol.PIPersonId);
                            string PIemail = PIPerson.Email;

                            if (PIemail.Length > 0)
                            {
                                EMailTemplate mailTemplate = new EMailTemplate(cachePolicy);
                                mailTemplate.Load(DataAccess.GetConnectionString(), "EIRBEMAILTYPE_PINOTIFY");


                                string fromEmail = Settings.GetKeyValue("Email.EIRBWorkflow.Sender", "InsightHelpDesk@Partners.org");
                                MailMessage message = new MailMessage(fromEmail, PIemail);
                                string subject = string.Format("eIRB Submission Update: {0} - {1}: {2}", protocol.ProtocolNumber, protocolProcess.Name, protocol.Title);
                                message.Subject = subject;
                                message.Body = mailTemplate.BodyText;
                                message.IsBodyHtml = true;

                                string smtpServer = Settings.GetKeyValue("Email.SMTPServer", "127.0.0.1");
                                SmtpClient client = new SmtpClient(smtpServer);
                                client.Send(message);

                                mailTemplate.Archive(PIemail, fromEmail, subject, smtpServer, DataAccess.GetConnectionString());
                            }
                        }
                    }
                }
                else if (protocolProcess.BeenSubmitted && !protocolProcess.Locked && ProtocolProcess.HasBeenLocked && !ResubmissionFlag)
                {
                    // here we need to get the Resubit workflow and move it through.
                    Validate(UserRequest.ResubmitWF);
                    /*Trackit 10114 
                    GenerateAndSaveApplicationDocuments is an ASYNC (one-way) call on DocumentUtility web service
                     * that will generate and store the application documents (VFA, VA, CV, IR) to SharePoint
                     It will OVERWRITE any existing documents on SharePoint. DeleteDocuments is not called to improve performance
                     */
                    try
                    {
                        DocumentUtility docUtil = new DocumentUtility();
                        string docStageFolderEntry = Utility.Settings.GetKeyValue("DocumentStagingFolder", "DocumentStagingFolder");
                        string docStagingFolder = string.Format(@"\\{0}",
                            Path.Combine(System.Web.HttpContext.Current.Server.MachineName, docStageFolderEntry));
                        docUtil.GenerateAndSaveApplicationDocuments(ProtocolProcess.Id, docStagingFolder, ProtocolProcess.ProtocolId);
                    }
                    catch (Exception ex)
                    {
                        Utility.ExceptionReport.WriteToEventLog("Failed to validate ,error occurred at ValidateSubmission()", ex, true, Utility.ExceptionReport.ReportType.Error);
                    }
                }
                    // If the process has come back to the submitter as regular rejection process and it is submitted
                else if (protocolProcess.BeenSubmitted && ResubmissionFlag)
                {
                    //Submit the application so that the item will go where it came from.
                    Validate(UserRequest.ApplicationSubmit);
                }
                else if (workflowExecutionID == 0)
                {
                    Validate(UserRequest.ApplicationSubmit);
                }

                //Make sure the text box and instructions become invisible after the submission
                submitApplication.Visible = false;
                reSubmission.Visible = false;
                instructions.Visible = true;

                /*TrackIt: 8345
				Register users associated with a protocol/process in Insight automatically*/
                registerAppStaff(protocolId);
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        private void registerAppStaff(int protocolId)
        {
            try
            {
                /*SOAP Station Changes*/
                InsightWebService.HumansWse HumansWse = new InsightWebService.HumansWse();
                //Get the service account credentials
                string serviceAccount = ConfigurationManager.AppSettings["ServiceAccount"]; // "rag29";  //read from web.config
                string serviceAccountPwd = ConfigurationManager.AppSettings["SAPassword"]; //"z0hcq";//read from web.config

                //Create our UsernameToken and supply the consumer credentials... 
                UsernameTokenProvider user =
                    new UsernameTokenProvider(@"partners\" + serviceAccount, serviceAccountPwd);

                //Create the policy assertion... 
                UsernameOverTransportAssertion assert = new UsernameOverTransportAssertion();
                assert.UsernameTokenProvider = user;
                assert.ServiceActor = @"http://partners.org/security/webservicesecurity";
                //Set the policy... 
                HumansWse.SetPolicy(new Microsoft.Web.Services3.Design.Policy(assert));
                /*SOAP Station Changes END*/


                HumansWse.RegistereIRBUser(DataAccess.ConnectionString, protocolId);
            }
            catch (Exception ex)
            {
                //email error 
                SendEmail(protocolId + "." + ex.Message);
            }
        }

        private void SendEmail(string msg)
        {
            //sends 2 emails if there is a failure to call RegisterStaffUser 02/11/2009 trackIt 4345.
            string FromEmail = ConfigurationManager.AppSettings["Email.EIRBWorkflow.Sender"]; //"PHS Helpdesk";
            string ToEmail = ConfigurationManager.AppSettings["Email.To.RegistereIRBUser"];

            MailMessage mailMessage = new MailMessage(FromEmail, ToEmail);
            mailMessage.Subject = ConfigurationManager.AppSettings["Environment"] + ": " + "Register Staff User Failed";
            mailMessage.Body = "Call to Web Service RegisterIRBUser Failed for Protocol Number: " + msg;

            SmtpClient client = new SmtpClient(ConfigurationManager.AppSettings["Email.SMTPServer"]);
            client.Send(mailMessage);
        }

        /// <summary>
        /// command event handler for the grid which playes the grid.
        /// </summary>
        /// <param name="source">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnLogItemItemCommand(object source, DataGridCommandEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                if (e.CommandName == "ItemNavigate")
                {
                    LogItem logItem = SetLogItemViewStatus(Convert.ToInt32(e.Item.Cells[1].Text.Trim()), source, e.Item.Cells[4].FindControl("completed"));
                    if (logItem.QuestionnaireAnswerId == 0 && logItem.QuestionnaireVersionId == 0)
                    {
                        OpenLogItem((int) ValidationFormType.StaffAndAccess);
                    }
                    else if (logItem.QuestionnaireAnswerId == -1 && logItem.QuestionnaireVersionId == -1)
                    {
                        OpenLogItem((int) ValidationFormType.Attachments);
                    }
                    else if ((logItem.QuestionnaireAnswerId == -2 && logItem.QuestionnaireVersionId == -2) || (logItem.Type.Trim().ToLower() == "sponsor/funding")) //primary sponsor is not added
                    {
                        OpenLogItem((int) ValidationFormType.ProtocolProcessOverview);
                    }
                    else
                    {
                        LoadObjectAndCache(logItem.QuestionnaireAnswerId, logItem.QuestionnaireVersionId);
                        OpenLogItem(GetLogItemHandler(logItem));
                    }
                }
            }
        }

        /// <summary>
        /// Get the log item handler from QuestionaireItem object
        /// </summary>
        /// <param name="logItem">Indicates the logitem info</param>
        private int GetLogItemHandler(LogItem logItem)
        {
            QuestionnaireItem qItem = new QuestionnaireItem(cachePolicy);
            return qItem.GetLogItemHandler(logItem.Description);
        }

        /// <summary>
        /// Opens the Logitem editor as a popup to error correction.
        /// </summary>
        /// <param name="redirect">Indicates an integer value to open up the specified form for edition</param>
        private void OpenLogItem(int redirect)
        {
            StringBuilder script = new StringBuilder();
            script.Append("\n<script language=JavaScript id='LogItem'>\n");
            script.Append("var editorWin = null; \n");
            cacheOutGoingData(true);
            if (redirect == 0)
            {
                script.Append("editorWin = window.open('StaffAndAccess.aspx', 'LogItem', 'width=1000, height=600, status=yes, toolbar=no, scrollbars=yes, resizable=yes'); \n");
            }
            else if (redirect == 2)
            {
                script.Append("editorWin = window.open('Attachments.aspx', 'LogItem', 'width=1000, height=600, status=yes, toolbar=no, scrollbars=yes,  resizable=yes'); \n");
            }
            else if (redirect == 3) //primary sponsor is not added
            {
                script.Append("editorWin = window.open('ProtocolProcessOverview.aspx', 'LogItem', 'width=1000, height=600, status=yes, toolbar=no, scrollbars=yes, resizable=yes'); \n");
            }
            else
            {
                script.Append("editorWin = window.open('AnswerEditor.aspx', 'LogItem', 'width=1000, height=600, status=yes, toolbar=no, scrollbars=yes, resizable=yes'); \n");
            }
            script.Append("</script>");
            if (!ClientScript.IsClientScriptBlockRegistered("LogItem"))
            {
                ClientScript.RegisterClientScriptBlock(GetType(), "LogItem", script.ToString());
            }
        }

        /// <summary>
        /// Caches outgoing data with incoming data key for use across pages.
        /// </summary>
        /// <param name="showTargetAsPopUp">set to true, if the target page is to be shown as a popup</param>
        private void cacheOutGoingData(bool showTargetAsPopUp)
        {
            Hashtable outgoingData = new Hashtable();
            outgoingData.Add(Keys.ProtocolProcessIdKey, protocolProcessId);
            outgoingData.Add(Keys.ProtocolIdKey, protocolId);
            outgoingData.Add(Keys.ProtocolAccessKey, userAccessLevel);
            outgoingData.Add(Keys.ShowAsPopUp, showTargetAsPopUp);
            pageCachePolicy.Cache(Keys.IncomingDataKey, outgoingData);
        }

        /// <summary>
        /// Eventhandler to change the viewed state of the LogItem.
        /// </summary>
        /// <param name="source">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnLogItemStatusChange(object source, EventArgs e)
        {
            CheckBox logItemViewed = (CheckBox) (source);
            DataGridItem gridItem = (DataGridItem) logItemViewed.NamingContainer;
            SetLogItemViewStatus(Convert.ToInt32(gridItem.Cells[1].Text.Trim()), source);
        }

        #endregion

        #region overrides

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            ClientScript.RegisterStartupScript(GetType(), "DisableValidationRunning", string.Format(
                "<script language='javascript'>\n" +
                    "function DisableValidationRunning()\n" +
                        "{{\n" +
                            "\tvar panel = document.getElementById('{0}');\n" +
                                "\tif (panel != null)\n" +
                                    "\t\tpanel.style['display'] = 'none';\n" +
                                        "\treturn true; \n" +
                                            "}}\n" +
                                                "DisableValidationRunning(); \n" +
                                                    "</script>", runningValidation.ClientID));

            ClientScript.RegisterClientScriptBlock(GetType(), "DisableErrorGridPanel", string.Format(
                "<script language='javascript'>\n" +
                    "function DisableErrorGridPanel()\n" +
                        "{{\n" +
                            "\ttry\n" +
                                "\t{{\n" +
                                    "\t\tvar panel = document.getElementById('{0}');\n" +
                                        "\t\tif (panel != null)\n" +
                                            "\t\t\t{{\n" +
                                                "\t\t\tpanel.style['display'] = 'none';\n" +
                                                    "\t\t\tvar waitPanel = document.getElementById('{1}');\n" +
                                                        "\t\t\tif (waitPanel != null)\n" +
                                                            "\t\t\t{{\n" +
                                                                "\t\t\t\twaitPanel.style['display'] = 'block';\n" +
                                                                    "\t\t\t}}\n" +
                                                                        "\t\t\tvar validateButton = document.getElementById('{2}'); \n" +
                                                                            "\t\t\tif (validateButton != null)\n" +
                                                                                "\t\t\t{{\n" +
                                                                                    //"\t\t\tvalidateButton.disabled = 'true'; \n" +
                                                                                    "\t\t\t\tif ( validateButton.alreadyClicked != null) \n" +
                                                                                        "\t\t\t\t{{\n" +
                                                                                            "\t\t\t\t\t return false; \n" +
                                                                                                "\t\t\t\t}}\n" +
                                                                                                    "\t\t\t\telse \n" +
                                                                                                        "\t\t\t\t{{\n" +
                                                                                                            "\t\t\t\tvalidateButton.alreadyClicked = true; \n" +
                                                                                                                "\t\t\t\t}}\n" +
                                                                                                                    "\t\t\t}}\n" +
                                                                                                                        "\t\t}}\n" +
                                                                                                                            "\t\tvar submitButton = document.getElementById('{3}'); \n" +
                                                                                                                                "\t\tif (submitButton != null)\n" +
                                                                                                                                    "\t\t{{\n" +
                                                                                                                                        //"\t\t\tvalidateButton.disabled = 'true'; \n" +
                                                                                                                                        "\t\t\tif ( submitButton.alreadyClicked != null) \n" +
                                                                                                                                            "\t\t\t{{\n" +
                                                                                                                                                "\t\t\t\t return false; \n" +
                                                                                                                                                    "\t\t\t}}\n" +
                                                                                                                                                        "\t\t\telse \n" +
                                                                                                                                                            "\t\t\t{{\n" +
                                                                                                                                                                "\t\t\tsubmitButton.alreadyClicked = true; \n" +
                                                                                                                                                                    "\t\t\t}}\n" +
                                                                                                                                                                        "\t\t}}\n" +
                                                                                                                                                                            "\t}}\n" +
                                                                                                                                                                                "\tcatch(x)\n" +
                                                                                                                                                                                    "\t{{\n" +
                                                                                                                                                                                        "\t\talert('Exception:' + x);\n" +
                                                                                                                                                                                            "\t}}\n" +
                                                                                                                                                                                                "\treturn true; \n" +
                                                                                                                                                                                                    "}}\n" +
                                                                                                                                                                                                        "\n" +
                                                                                                                                                                                                            "</script>", errorGridPanel.ClientID, runningValidation.ClientID, validateApplication.ClientID, submitApplication.ClientID));
        } //runningValidation

        #endregion

        #region Web Form Designer generated code

        /// <summary>
        /// Event handler for the OnInit.
        /// </summary>
        /// <param name="e">Arguments associated with the event.</param>
        protected override void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
            cachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
            pageCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.PageCachePolicyKey];
            validateApplication.Attributes["onclick"] = "return DisableErrorGridPanel(); ";
            submitApplication.Attributes["onclick"] = "return DisableErrorGridPanel(); ";
        }

        /// <summary>
        /// Initializes all the component of a page
        /// </summary>
        /// <param name="e">Arguments associated with the event.</param>
        private void InitializeComponent()
        {
            this.header.Navigate += new System.Web.UI.WebControls.CommandEventHandler(this.OnNavigate);
            this.humansSubModNavigation.Navigate += new PHSRAG.Insight21.InsightWebControls.HumansSubModuleNavigation.NavigateEventHandler(this.OnHumansSubModNavigate);
            this.animalsSubModNavigation.Navigate += new System.Web.UI.WebControls.CommandEventHandler(this.OnHumansSubModNavigate);
            this.breadCrumb.Navigate += new System.Web.UI.WebControls.CommandEventHandler(this.OnBreadCrumbNavigate);
            this.errorGrid.ItemCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.OnLogItemItemCommand);
            this.submitApplication.Click += new System.Web.UI.ImageClickEventHandler(this.OnApplicationSubmit);
            this.validateApplication.Click += new System.Web.UI.ImageClickEventHandler(this.OnApplicationReview);
            this.Load += new System.EventHandler(this.OnPageLoad);
        }

        #endregion

        /// <summary>
        /// Resets the subnavigation selected link before the breadCrumb performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnBreadCrumbNavigate(object sender, CommandEventArgs e)
        {
            humansSubModNavigation.Reset();
        }

        /// <summary>
        /// Uncahce, load and cache (Refresh) Protocol and Protocol Process objects.
        /// </summary>
        private void RefreshObjects()
        {
            //If the protocol / protocolprocess need to be uncached because they were submitted to workflow, do it now            
            cachePolicy.UnCache(Protocol.ProtocolKey);
            cachePolicy.UnCache(ProtocolProcess.ProtocolProcessKey);

            protocol = Protocol;
            protocolProcess = ProtocolProcess;
        }

        /// <summary>
        /// Resets the subnavigation selected link before the header performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnNavigate(object sender, CommandEventArgs e)
        {
            humansSubModNavigation.Reset();
            humansSubNavigation.Reset();
        }

        /// <summary>
        /// Constructs and caches a hashtable of data for use by the page to which nagivation leads
        /// </summary>
        private void OnHumansSubModNavigate(object sender, EventArgs e)
        {
            OnHumansSubModNavigate();
        }

        /// <summary>
        /// Constructs and caches a hashtable of data for use by the page to which nagivation leads
        /// </summary>
        private void OnHumansSubModNavigate()
        {
            cacheOutGoingData(false);
        }

        #region Private methods

        /// <summary>
        /// Hide all controls as part of setting the submission stage
        /// </summary>
        private void HideControls()
        {
            // Instruction Labels
            initialInstructions.Visible = reviewInstructions.Visible = submitInstructions.Visible =
                resubmitInstructions.Visible = resubmitErrorInstructions.Visible = submitComplete.Visible =
                    resubmitInitialInstructions.Visible = resubmitComplete.Visible = false;

            // ImageButton
            submitApplication.Style["display"] = "none";
            validateApplication.Visible = false;

            // HtmlInputImage
            viewApplication.Visible = viewFullApplication.Visible = false;

            // Panel
            errorGridPanel.Visible = false;
        }

        /// <summary>
        /// Set the User interface according to the process status
        /// </summary>
        /// <param name="process">Process enumeration- status of the application process.</param>
        /// <param name="args">optional parameter which takes the LogItem arrayList to be displayed .</param>
        private void SetSubmissionStage(SubmissionStage process, params object[] args)
        {
            HideControls();

            if (process == SubmissionStage.InitialReview)
            {
                initialInstructions.Visible = true;
                validateApplication.Visible = true;

                if (protocolProcess.HasBeenLocked)
                {
                    initialInstructions.Visible = false;
                    resubmitInitialInstructions.Visible = true;
                }
            }
            else if (process == SubmissionStage.ErrorReview)
            {
                reviewInstructions.Visible = true;
                submitApplication.Style["display"] = "block";

                if (ProtocolProcess.BeenSubmitted)
                {
                    resubmitErrorInstructions.Visible = true;
                    reviewInstructions.Visible = false;
                }

                if (args.Length == 1)
                {
                    errorGrid.DataSource = args[0];
                    errorGrid.DataBind();
                    errorGridPanel.Visible = true;
                    validateApplication.Visible = true;
                    submitApplication.Style["display"] = "none";
                }
            }
            else if (process == SubmissionStage.Submit)
            {
                submitInstructions.Visible = true;

                viewApplication.Visible = true;
                viewFullApplication.Visible = true;

                submitApplication.Style["display"] = "block";

                if (WorkflowExecutionID != 0 && ResubmissionFlag)
                {
                    reSubmission.Visible = true;
                    submitApplication.ImageUrl = "../Images/b_resubmit.gif";
                    instructions.Visible = false;
                }
                else
                {
                    reSubmission.Visible = false;
                    submitApplication.ImageUrl = "../Images/b_submit.gif";
                    instructions.Visible = true;
                }
            }
            else if (process == SubmissionStage.SubmitComplete)
            {
                submitComplete.Visible = true;

                validateApplication.Visible = true;

                viewApplication.Visible = true;
                viewFullApplication.Visible = true;
            }
            else if (process == SubmissionStage.ResubmissionNoWFComplete || process == SubmissionStage.ResubmissionComplete)
            {
                resubmitComplete.Visible = true;

                viewApplication.Visible = true;
                viewFullApplication.Visible = true;
            }
            else if (process == SubmissionStage.ResubmissionNoWF || process == SubmissionStage.Resubmission)
            {
                resubmitInstructions.Visible = true;

                submitApplication.ImageUrl = "../Images/b_submit.gif";
                submitApplication.Style["display"] = "block";

                viewApplication.Visible = true;
                viewFullApplication.Visible = true;
            }
        }

        /// <summary>
        /// Change the viewed status of the logItem (Save the changes to the database)
        /// </summary>
        /// <param name="logItemId">The Id of the LogItem which needs to be updated</param>
        /// <param name="args">The Control type that initaited the action</param>
        private LogItem SetLogItemViewStatus(int logItemId, params object[] args)
        {
            LogItem logItem = new LogItem(cachePolicy);
            string connection = DataAccess.GetConnectionString();
            logItem.Load(connection, Convert.ToInt32(logItemId));

            if (args[0].ToString() == "System.Web.UI.WebControls.CheckBox")
            {
                logItem.Completed = ((CheckBox) args[0]).Checked;
            }
            else
            {
                logItem.Completed = true;
                ((CheckBox) args[1]).Checked = true;
            }
            logItem.Save(connection);
            return logItem;
        }

        /// <summary>
        /// Load the questionnaire version and the questionnaire answer and cache it
        /// </summary>
        /// <param name="questionnaireAnswerId">questionnaireAnswerId to load and cache the Questionnaire answers</param>
        /// <param name="questionnaireVersionId">questionnaireverison Id to load and cache the questionnaire version </param>
        private void LoadObjectAndCache(int questionnaireAnswerId, int questionnaireVersionId)
        {
            string connection = DataAccess.GetConnectionString();
            QuestionnaireAnswer qA = new QuestionnaireAnswer(cachePolicy);
            qA.Load(connection, questionnaireAnswerId);
            qA.Answers = Answer.GetAnswers(qA.Id, cachePolicy);
            QuestionnaireVersion qV = new QuestionnaireVersion(cachePolicy);
            qV.Load(connection, questionnaireVersionId);
            qV.Items = QuestionnaireItem.GetQuestionnaireVersionItems(cachePolicy, qV.Id);
            cachePolicy.Cache(qA.CacheKey(), qA);
            cachePolicy.Cache(qV.CacheKey(), qV);
        }

        /// <summary>
        /// Validate the protocol process (checks the availablity of answers for all the questionnaire item in the questionnaires)and displays the user interface accordingly
        /// </summary>
        /// <param name="userRequest">UserRequest enumeration- EventHandler that iniitiated the action.</param>
        private void Validate(UserRequest userRequest)
        {
            ArrayList logItems = ValidateProcess(protocolProcess, cachePolicy);

            HumansWorkFlow.InsightApplicationName = Settings.GetKeyValue("InsightApplicationName", "EIRBWFApp");
            if (protocolProcess.Validated)
            {
                switch (userRequest)
                {
                    case UserRequest.ApplicationReview:

                        if (!protocolProcess.Locked && protocolProcess.BeenSubmitted && !protocolProcess.HasBeenLocked && !ResubmissionFlag)
                        {
                            if (WorkflowExecutionID == 0)
                            {
                                SetSubmissionStage(SubmissionStage.Submit);
                            }
                            else
                            {
                                SetSubmissionStage(SubmissionStage.ResubmissionNoWF);
                            }
                        }
                        else if (!protocolProcess.Locked && protocolProcess.BeenSubmitted && protocolProcess.HasBeenLocked && !ResubmissionFlag)
                        {
                            SetSubmissionStage(SubmissionStage.Resubmission);
                        }
                        else
                        {
                            SetSubmissionStage(SubmissionStage.Submit);
                        }
                        break;

                    case UserRequest.Resubmit:
                        SetSubmissionStage(SubmissionStage.ResubmissionNoWFComplete);
                        break;

                    case UserRequest.ApplicationSubmit:
                        //If the current protocol process has already submitted in Workflow then 
                        //do not call InitiateWorkFlow method. Call direct Skelta approval.
                        //Submitter will do Rejection from usual Workflow detail screen.                        

                        //Every time the run review is being executed it resets the status to WIP so this code
                        //executes in case the submission being run twice and if user submits it again the status 
                        //never changes.
                        if ((WorkflowExecutionID == 0 || protocolProcess.Status == "PPSTATUS_WIP") && !protocolProcess.BeenSubmitted)
                        {
                            SkeltaWF.InitiateWorkFlow(
                                protocolProcess,
                                Constants.WorkFlow.Initial,
                                (header.ModuleName.ToLower() == "humans") ?
                                                                              Constants.MainWorkFlow.Humans : Constants.MainWorkFlow.Animals);
                            SetSubmissionStage(SubmissionStage.SubmitComplete);
                        }
                        else
                        {
                            ApprovalDecisionHandler approval = new ApprovalDecisionHandler();
                            // Calling the ApprovalActionEvent of ApprovalDecisionHandler class to alert the engine with "Approved" status
                            // and to update Skelta tables (SWActivityList and SWExectuionDetails) appropriately
                            int workflowExecutionID = SkeltaWF.GetLatestSubmitterActivityId(WorkflowExecutionID);

                            if (workflowExecutionID == 0)
                            {
                                workflowExecutionID = WorkflowExecutionID;
                            }

                            if (workflowExecutionID > 0)
                            {
                                try
                                {
                                    approval.ApprovalActionEvent(workflowExecutionID,
                                        ApprovalActionType.Approved,
                                        HumansWorkFlow.InsightApplicationName,
                                        header.ModuleName.ToLower() == "humans" ? Constants.MainWorkFlow.Humans : Constants.MainWorkFlow.Animals,
                                        comments.Text);
                                    SetSubmissionStage(SubmissionStage.SubmitComplete);
                                }
                                catch
                                {
                                    SetSubmissionStage(SubmissionStage.Submit);
                                }
                            }
                            else
                            {
                                SetSubmissionStage(SubmissionStage.Submit);
                            }
                        }
                        validateApplication.Visible = false;
                        RefreshObjects();
                        break;
                        // resubmit through WF
                    case UserRequest.ResubmitWF:

                        protocolProcess.Resubmission = true;
                        protocolProcess.Save(DataAccess.GetConnectionString());

                        // change this to get a type, or get a new one each time of type RESUB.

                        //SkeltaWFlow.HumansWorkFlow skeltaWF=new PHSRAG.Insight21.InsightWorkFlow.HumansWorkFlow(cachePolicy);
                        /// chreate a new InitiateResubmitWorkflow
                        SkeltaWF.InitiateWorkFlow(protocolProcess, Constants.WorkFlow.Resubmission,
                            (header.ModuleName.ToLower() == "animals") 
                            ? Constants.MainWorkFlow.Animals 
                            : Constants.MainWorkFlow.Humans);
                        SetSubmissionStage(SubmissionStage.ResubmissionComplete);
                        validateApplication.Visible = false;
                        RefreshObjects();
                        break;
                }
                protocolProcess.Validated = true;
            }
            else
            {
                if (logItems != null)
                {
                    SetSubmissionStage(SubmissionStage.ErrorReview, logItems);
                }
                else
                {
                    SetSubmissionStage(SubmissionStage.InitialReview);
                }
            }
        }

        /// <summary>
        /// This method is used to get workflow Execution for particular Protocol Process.
        /// There is a crossreference table between Protocol Process and Workflow Execution Id.
        /// The execution Id is used for all Skela workflow related operations.
        /// </summary>
        /// <returns>Workflow execution Id</returns>
        private int GetWorkflowExecutionId(string type)
        {
            int wfExecutionID = 0;
            try
            {
                if (protocolProcess != null)
                {
                    wfExecutionID = SkeltaWF.GetWorkflowItemIdByType(protocolProcess.Id, type);
                }
            }
            catch (Exception ex)
            {
                ExceptionReport.WriteToEventLog("Error occurred while getting Workflow execution Id", ex, true, ExceptionReport.ReportType.Error);
                annunciator.Message = "Error occurred while getting Workflow execution Id";
            }

            return wfExecutionID;
        }

        /// <summary>
        /// Validates the protocol process in the page.
        /// </summary>
        /// <param name="theProcess"></param>
        /// <param name="policy"></param>
        /// <returns></returns>
        private ArrayList ValidateProcess(ProtocolProcess theProcess, ICachePolicy policy)
        {
            try
            {
                theProcess.RemoveLogItems();
                ProtocolVersion protocolVersion = theProcess.GetLatestProtocolVersion(false, policy);
                if (protocolVersion == null)
                {
                    throw new Exception("No protocol version found");
                }
                ArrayList questionnaireAnswers = protocolVersion.GetQuestionnaireAnswers(policy);

                foreach (QuestionnaireAnswer qA in questionnaireAnswers)
                {
                    QuestionnaireVersion questionnaireVersion = new QuestionnaireVersion(policy);
                    questionnaireVersion.Load(DataAccess.GetConnectionString(), qA.QuestionnaireVersionId);

                    ArrayList questionnaireItems = questionnaireVersion.Items;

                    foreach (QuestionnaireItem parentQuestionnaireItem in questionnaireItems)
                    {
                        if ((string.IsNullOrEmpty(parentQuestionnaireItem.ParentName))
                            && qA.Action == (int) QuestionnaireAnswer.UserAction.Edit)
                        {
                            // the QA will have the default name if the form hasn't been filled out but the user clicked
                            // on the link to fill out the form and then clicked cancel, HOWEVER, in the case of the 
                            // children form, the user could skip the name for the children and fill out other questions.
                            // We need to consider this a questionnaire that is invalid
                            if ((qA.Name == FormsManagement.Constants.QuestionnaireAnswerDefaultNames.Children)
                                && (qA.Answers.Count > 0))
                            {
                                theProcess.checkRequiredItems(parentQuestionnaireItem, parentQuestionnaireItem.ParentValue, qA, questionnaireVersion);
                            }
                            else if ((qA.Name != FormsManagement.Constants.QuestionnaireAnswerDefaultNames.Drugs) &&
                                (qA.Name != FormsManagement.Constants.QuestionnaireAnswerDefaultNames.MedicalDevices) &&
                                    (qA.Name != FormsManagement.Constants.QuestionnaireAnswerDefaultNames.Sponsor_AM) &&
                                        (qA.Name != FormsManagement.Constants.QuestionnaireAnswerDefaultNames.Children))
                            {
                                theProcess.checkRequiredItems(parentQuestionnaireItem, parentQuestionnaireItem.ParentValue, qA, questionnaireVersion);
                            }
                        }
                    }
                    Script validationScript =
                        (Script) questionnaireVersion.Scripts[FormsManagement.Constants.ScriptType.Validation];

                    if (validationScript != null && validationScript.ScriptText != null)
                    {
                        using (ScriptEngineHost scriptHost =
                            new ScriptEngineHost
                                (string.Format("{0}{1}", ScriptEngine.Constants.RootMoniker.ValidationScriptMoniker,
                                    questionnaireVersion.Id),
                                    ScriptEngine.Constants.RootNamespaces.ValidationScript, true))
                        {
                            ArrayList refs = ScriptReference.GetAllScriptReferences(DataAccess.GetConnectionString());

                            for (int i = 0; i < refs.Count; ++i)
                            {
                                ScriptReference reference = (ScriptReference) refs[i];
                                scriptHost.AddDLLReference(reference.Path);
                            }

                            Protocol currentProtocol = new Protocol(policy);
                            currentProtocol.Load(DataAccess.GetConnectionString(), protocolId);
                            scriptHost.AddIntrinsicObject("intrinsicProtocol", currentProtocol);

                            scriptHost.AddIntrinsicObject("intrinsicProtocolProcess", theProcess);

                            scriptHost.AddIntrinsicObject("intrinsicQuestionnaireAnswer", qA);

                            scriptHost.AddIntrinsicObject("intrinsicProtocolVersion", protocolVersion);

                            scriptHost.AddIntrinsicObject("intrinsicCachePolicy", policy);

                            scriptHost.AddIntrinsicObject("intrinsicConnection", DataAccess.GetConnectionString());
                            try
                            {
                                if (scriptHost.Compile(validationScript))
                                {
                                    scriptHost.RunScript(validationScript, "ValidationScript.Script", "Main");
                                }
                            }
                            catch (Exception ex)
                            {
                                ExceptionReport.WriteToEventLog("Failed to validate ,validation script error occurred ", ex, true, ExceptionReport.ReportType.Error);
                                throw;
                            }
                        }
                    }
                }
                ArrayList logItemList = LogItem.GetLogItems(theProcess.Id, policy);

                if (logItemList.Count == 0)
                {
                    theProcess.Validated = true;
                    logItemList = null;
                }
                else
                {
                    theProcess.Validated = false;
                }

                theProcess.Save(DataAccess.GetConnectionString());
                return logItemList;
            }

            catch (Exception e)
            {
                ExceptionReport.WriteToEventLog("Failed to validate ,error occurred at ValidateSubmission()", e, true, ExceptionReport.ReportType.Error);
                throw;
            }
        }

        /// <summary>
        /// Validates process status of protocol process under the context of protocol level
        /// mainly for CR, if status of either "submitted" or "pending", the user will receive an error message.
        /// </summary>
        /// <param name="theProcess"></param>
        /// <param name="currentProtocol"></param>
        /// <returns></returns>
        private void ValidateSubmissionStatus(ProtocolProcess theProcess, Protocol currentProtocol)
        {
            foreach (ProtocolProcess p in currentProtocol.ProtocolProcesses)
            {
                if (theProcess.Id != p.Id && p.Type == Constants.ProtocolProcessType.ContinuingReview && (p.Status == Constants.ProtocolProcessStatus.Pending || p.Status == Constants.ProtocolProcessStatus.Submitted))
                {
                    throw new Exception(CRSubmittedErrorMsg);
                }
            }
        }

        #endregion

        #region Enum

        #region Nested type: SubmissionStage

        /// <summary>
        /// Enum for the Process status
        /// </summary>
        private enum SubmissionStage
        {
            InitialReview,
            ErrorReview,
            Submit,
            SubmitComplete,
            ResubmissionNoWF,
            ResubmissionNoWFComplete,
            Resubmission,
            ResubmissionComplete
        }

        #endregion

        #region Nested type: UserRequest

        /// <summary>
        /// Enum for the eventHandlers that initiatiated the validation process 
        /// </summary>
        private enum UserRequest
        {
            ApplicationReview,
            ApplicationSubmit,
            InitialRequest,
            Resubmit,
            ResubmitWF
        }

        #endregion

        #endregion
    }
}